home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / macabuse / imlib / port / sgi / sound.c < prev    next >
C/C++ Source or Header  |  1997-05-20  |  7KB  |  315 lines

  1. /*************************************
  2.   Threaded sound driver system
  3. **************************************/
  4.  
  5. // comminicates with sound sub-system via shared memory
  6.  
  7. #include "macs.hpp"
  8. #include "sound.hpp"
  9. #include "readwav.hpp"
  10. #include "dprint.hpp"
  11. #include "jmalloc.hpp"
  12. #include <sys/types.h>
  13. #include <sys/ipc.h>
  14. #include <sys/shm.h>
  15. #include "timing.hpp"
  16. #include <sys/ipc.h>
  17. #include <sys/shm.h>
  18. #include <signal.h>
  19. #include <unistd.h>
  20.  
  21. enum { SFXCMD_QUIT,
  22.        SFXCMD_REGISTER,
  23.        SFXCMD_UNREGISTER,
  24.        SFXCMD_PLAY
  25.      };
  26.  
  27. #define DIN_NAME  "/tmp/sfxdrv.signal"
  28. #define DOUT_NAME "/tmp/sfxdrv.command"
  29.  
  30. class sfx_handle
  31. {
  32.   public :
  33.   int shm_id;
  34.   sound_effect *me;
  35.   sfx_handle   *next;  
  36.   void         *user_data_pointer;
  37.   void         *shm_data_pointer;
  38.   sfx_handle(sound_effect *Me, sfx_handle *Next, void  *UData, void  *SData, int Shm_id)
  39.   { me=Me;
  40.     next=Next;
  41.     shm_id=Shm_id;
  42.     user_data_pointer=UData;
  43.     shm_data_pointer=SData;
  44.   }
  45. } ;
  46.  
  47. static sfx_handle *sfx_list=NULL;
  48. static ushort last_allocated_sfx_id=0;
  49. static int sfx_driver_out_fd=-1,sfx_driver_in_fd=-1;
  50. static int sdriver_pid=0;
  51.  
  52.  
  53. static void kill_sound_driver()
  54. {
  55.   if (sfx_driver_out_fd>=0)
  56.   {
  57.     uchar cmd=SFXCMD_QUIT;        // failed, tell the driver good-bye
  58.     write(sfx_driver_out_fd,&cmd,1);
  59.     close(sfx_driver_out_fd);
  60.     close(sfx_driver_in_fd);
  61.     sfx_driver_out_fd=-1;
  62.  
  63.     milli_wait(10);
  64.     kill(sdriver_pid,SIGUSR1);
  65.     unlink(DIN_NAME);
  66.     unlink(DOUT_NAME);
  67.   }
  68. }
  69.  
  70.  
  71.  
  72. #ifdef __sgi
  73. static void sfx_clean_up(...)
  74. #else
  75. static void sfx_clean_up(int why)      // on exit unattach all shared memory links
  76. #endif
  77. {  
  78.   while (sfx_list)
  79.   {
  80.     if (sfx_driver_out_fd>=0)
  81.     {
  82.       int fail=0;
  83.       uchar cmd=SFXCMD_UNREGISTER;
  84.       if (write(sfx_driver_out_fd,&cmd,1)!=1)
  85.         fail=1;
  86.       else if (write(sfx_driver_out_fd,&sfx_list->shm_id,
  87.              sizeof(sfx_list->shm_id))!=sizeof(sfx_list->shm_id))
  88.         fail=1;
  89.       if (fail) 
  90.       { kill_sound_driver(); }
  91.     }
  92.  
  93.     shmdt((char *)sfx_list->shm_data_pointer);  // detach the shared memory from us
  94.  
  95.     sfx_handle *last=sfx_list;
  96.     sfx_list=sfx_list->next;
  97.     jfree(last);
  98.   }
  99. }
  100.  
  101.  
  102.  
  103. #define TOTAL_SIGS 29
  104.  
  105. int sigs[TOTAL_SIGS]={SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGTRAP,
  106.               SIGABRT,SIGIOT,SIGBUS,SIGFPE,SIGKILL,
  107.               SIGUSR1,SIGSEGV,SIGUSR2,SIGPIPE,SIGALRM,
  108.               SIGTERM,SIGCHLD,SIGCONT,SIGSTOP,
  109.               SIGTSTP,SIGTTIN,SIGTTOU,SIGIO,
  110.               SIGURG,SIGXCPU,SIGXFSZ,SIGVTALRM,SIGPROF,
  111.               SIGWINCH};
  112.  
  113. #include <errno.h>
  114.  
  115. sound_effect::sound_effect(char *filename)
  116. {
  117.   if (sfx_driver_out_fd>=0)
  118.   {
  119.     long sample_speed;
  120.     void *dat=read_wav(filename,sample_speed,size); 
  121.  
  122.     int id=shmget(IPC_PRIVATE,size,IPC_CREAT | 0777);
  123.     if (id==-1)
  124.     {
  125.       dprintf("Unable to allocate a shared memory id, please clean up\n");
  126.       jfree(dat);
  127.       data=NULL;
  128.     } else
  129.     {
  130.       void *shm_addr=shmat(id,NULL,0);  // attach as read/write
  131.       if ((long)shm_addr==-1)                   // if not able to attach
  132.       {
  133.     dprintf("shmat failed, too many shared memory segements or permission denied\n");
  134.     if (shmctl(id,IPC_RMID,NULL)!=0)
  135.       dprintf("shmctl failed, why?\n");
  136.     jfree(dat);
  137.     data=NULL;
  138.       } else
  139.       {
  140.     memcpy(shm_addr,dat,size);
  141.     jfree(dat);
  142.  
  143.     int fail=0;
  144.     uchar cmd=SFXCMD_REGISTER;
  145.     if (write(sfx_driver_out_fd,&cmd,1)==0)
  146.       fail=1;
  147.     else if (write(sfx_driver_out_fd,&id,sizeof(id))!=sizeof(id))
  148.       fail=1;
  149.     else if (write(sfx_driver_out_fd,&size,sizeof(size))!=sizeof(size))
  150.       fail=1;
  151.     else if (read(sfx_driver_in_fd,&cmd,1)!=1)
  152.       fail=1;
  153.     else if (cmd!=1)    // did we get an 'OK' back so when can delete the shm ID?
  154.       fail=1;
  155.  
  156.     if (shmctl(id,IPC_RMID,NULL)!=0)
  157.       dprintf("shmctl failed, why?\n");
  158.  
  159.     if (fail)
  160.     {
  161.       kill_sound_driver();
  162.       shmdt((char *)shm_addr);
  163.       data=NULL;
  164.     } else 
  165.     {
  166.       sfx_list=new sfx_handle(this,sfx_list,dat,shm_addr,id);    
  167.       data=(void *)sfx_list;
  168.     }
  169.       }      
  170.     }
  171.   }
  172. }
  173.  
  174.  
  175. sound_effect::~sound_effect()
  176. {
  177.   if (sfx_driver_out_fd>=0 && data)
  178.   { 
  179.     sfx_handle *h=(sfx_handle *)data;
  180.     uchar cmd=SFXCMD_UNREGISTER;
  181.     int fail=0;
  182.     if (write(sfx_driver_out_fd,&cmd,1)!=1)
  183.       fail=1;
  184.     else if (write(sfx_driver_out_fd,&h->shm_id,sizeof(h->shm_id))!=sizeof(h->shm_id))
  185.       fail=1;
  186.  
  187.     if (fail)
  188.     { kill_sound_driver(); }
  189.  
  190.     shmdt((char *)h->shm_data_pointer);
  191.       
  192.   }
  193. }
  194.  
  195.  
  196. void sound_effect::play(int volume, int pitch, int panpot)
  197. {
  198.   if (sfx_driver_out_fd>=0 && data)
  199.   {   
  200.     sfx_handle *h=(sfx_handle *)data;
  201.     uchar cmd=SFXCMD_PLAY;
  202.     int fail=0;
  203.     if (write(sfx_driver_out_fd,&cmd,1)!=1)
  204.       fail=1;
  205.     else if (write(sfx_driver_out_fd,&h->shm_id,sizeof(h->shm_id))!=sizeof(h->shm_id))
  206.       fail=1;
  207.     else if (write(sfx_driver_out_fd,&volume,sizeof(volume))!=sizeof(volume))
  208.        fail=1;
  209.  
  210.     if (fail) 
  211.        kill_sound_driver();
  212.   }
  213. }
  214.  
  215.  
  216. int sound_init(int argc, char **argv) 
  217. {
  218.   int i;
  219.   for (i=1;i<argc;i++)
  220.   {
  221.     if (!strcmp(argv[i],"-nosound"))
  222.     {
  223.       dprintf("sound : disabled with (-nosound)\n");
  224.       sfx_driver_out_fd=-1;
  225.       return 0;
  226.     }
  227.   }
  228.  
  229. #ifdef __linux__
  230.   FILE *sfx_driver_fp=popen("lnx_sdrv","r");
  231. #else
  232.   FILE *sfx_driver_fp=popen("sgi_sdrv","r");
  233. #endif
  234.  
  235.   if (!sfx_driver_fp)
  236.   {
  237.     dprintf("Error starting sound effect, could not run sgisfx_driver\n"
  238.         "make sure it is in your path and you execute permission\n");
  239.     sfx_driver_out_fd=-1;
  240.     return 0;
  241.   }
  242.  
  243.   char str[100];
  244.   if (!fgets(str,100,sfx_driver_fp) || !sscanf(str,"%d",&sdriver_pid) || sdriver_pid<0)
  245.   {
  246.     pclose(sfx_driver_fp);
  247.     dprintf("sound effects driver returned failure, sound effects disabled\n");
  248.     pclose(sfx_driver_fp);
  249.     sfx_driver_out_fd=-1;
  250.     return 0;
  251.   } else
  252.   {
  253.     pclose(sfx_driver_fp);
  254.  
  255.     do
  256.     { milli_wait(50);
  257.     } while (access(DIN_NAME,R_OK)); 
  258.     sfx_driver_in_fd=open(DIN_NAME,O_RDWR);
  259.  
  260.     do
  261.     { milli_wait(50);
  262.     } while (access(DOUT_NAME,W_OK)); 
  263.     fprintf(stderr,"opening %s for writing\n",DOUT_NAME);
  264.     sfx_driver_out_fd=open(DOUT_NAME,O_RDWR);
  265.  
  266.     for (int i=0;i<TOTAL_SIGS;i++)
  267.        signal(sigs[i],sfx_clean_up);
  268.  
  269.     atexit(sound_uninit);
  270.   }
  271.   
  272.   return SFX_INITIALIZED;
  273. }
  274.  
  275.  
  276. void sound_uninit()
  277. {
  278.   if (sfx_driver_out_fd>=0)
  279.   {
  280.     if (sfx_list)
  281.     {
  282. #ifdef __sgi
  283.       sfx_clean_up();
  284. #else
  285.       sfx_clean_up(1);
  286. #endif
  287.     }
  288.    
  289.     uchar cmd;
  290.     cmd=SFXCMD_QUIT;
  291.     write(sfx_driver_out_fd,&cmd,1);   // send quit commmand to the driver
  292.     close(sfx_driver_out_fd);          // close connection
  293.     close(sfx_driver_in_fd);          // close connection
  294.     sfx_driver_out_fd=-1;
  295.     sfx_driver_in_fd=-1;
  296.   }
  297. }
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304. song::song(char *filename) { ; }
  305.  
  306. void song::play(unsigned char volume) { ; }
  307. int song::playing() { return 0; }
  308. void song::set_volume(int vol)  { ; }
  309. void song::stop(long fadeout_time) { ;  }
  310. int playing() { return 0; }
  311. song::~song() { ; }
  312.  
  313.  
  314.  
  315.